//
// Created by lwj12 on 24-8-6.
//
#include "Date.h"
void Date::Print()
{
    cout << _year << "-" << _month << "-" << _day << endl;
}

Date :: Date(int year, int month, int day)
{
    assert(month > 0 && month < 13 && day > 0 && day < 32);
    _year = year;
    _month = month;
    _day = day;
}

Date :: ~Date()
{
    _year = -1;
    _month = -1;
    _day = -1;
}

Date::Date(const Date& d)
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
}

Date& Date::operator=(const Date &d)
{
    if(this != &d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    return *this;
}

int Date::operator-(const Date& d)
{
    int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int month1 = 0, month2 = 0;
    if((_year % 4 == 0 && _year % 100 != 0) || _year % 400 == 0)
    {
        day[1]++;
        for(int i = 0; i < _month - 1; i++) month1 += day[i];
        if((d._year % 4 == 0 && d._year % 100 != 0) || d._year % 400 == 0)
            for(int i = 0; i < d._month - 1; i++) month2 += day[i];
        else
        {
            day[1]--;
            for(int i = 0; i < d._month - 1; i++) month2 += day[i];
        }
    }
    else
    {
        for(int i = 0; i < _month - 1; i++) month1 += day[i];
        if((d._year % 4 == 0 && d._year % 100 != 0) || d._year % 400 == 0)
        {
            day[1]++;
            for(int i = 0; i < d._month - 1; i++) month2 += day[i];
        }
        else for(int i = 0; i < d._month - 1; i++) month2 += day[i];
    }
    return abs((_year * 365 + (_year - 1) / 4 - (_year - 1) / 100 + (_year - 1) / 400 + month1 + _day)
               - (d._year * 365 + (d._year - 1) / 4 - (d._year - 1) / 100 + (d._year - 1) / 400 + month2 + d._day));
}

Date Date::operator+(int d)
{
    Date D = *this;
    int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    D._day += d;
    while(D._day > day[D._month - 1])
    {
        D._day -= day[D._month - 1];
        if(D._month == 2 && ((D._year % 4 == 0 && D._year % 100 != 0) || D._year % 400 == 0) )  D._day -= 1;
        D._month++;
        if(D._month == 13)
        {
            D._month = 1;
            D._year++;
        }
    }
    return D;
}

Date& Date::operator+=(int day)
{
    *this = *this + day;
    return *this;
}

Date& Date::operator-=(int day)
{
    _day -= day;
    while(_day < 0)
    {
        _month--;
        if(_month == 0)
        {
            _year--;
            _month = 12;
        }
        _day += GetMonthDay(_year, _month);
    }
    return *this;
}

Date Date::operator-(int day)
{
    Date tmp;
    tmp -= day;
    return tmp;
}

bool Date::operator<(const Date& d)
{
    if(_year < d._year) return true;
    else if(_year == d._year)
    {
        if(_month < d._month) return true;
        else if(_month == d._month) return _day < d._day;
    }
    return false;
}

bool Date::operator==(const Date& d)
{
    return _year == d._year && _month == d._month && _day == d._day;
}

bool Date::operator<=(const Date& d)
{
    return operator<(d) || operator==(d);
}

bool Date::operator>(const Date& d)
{
    return !operator<=(d);
}

bool Date::operator>=(const Date& d)
{
    return !operator<(d);
}

Date& Date::operator++()
{
    *this += 1;
    return *this;
}

Date Date::operator++(int)
{
    Date tmp = *this;
    *this += 1;
    return tmp;
}

ostream& operator<<(ostream& out, const Date& d)
{
    out << d._year << " - " << d._month << " - " << d._day << endl;
    return out;
}

istream& operator<<(istream& in, Date& d)
{
    in >> d._year >> d._month >> d._day;
    assert(d._month > 0 && d._month < 13 && d._day > 0 && d._day < 32);
    return in;
}

